import cv2
import numpy as np
import pyautogui
import win32gui
import win32con
from typing import Dict, List, Optional, Tuple
import logging
from enum import Enum
from chart_capturer import ChartCapturer
import time
import os

class SignalType(Enum):
    BUY = "BUY"
    SELL = "SELL"
    CLOSE_BUY = "CLOSE_BUY"
    CLOSE_SELL = "CLOSE_SELL"
    NO_SIGNAL = "NO_SIGNAL"

class ChartAnalyzer:
    def __init__(self, chart_capturer: ChartCapturer):
        """
        初始化图表分析器
        :param chart_capturer: ChartCapturer实例，用于获取图表图像
        """
        self.chart_capturer = chart_capturer
        self.templates = {}  # 暂时不加载模板
        self.indicators = {}  # 存储技术指标
        self.chart_handles = {}  # 存储图表窗口句柄
        self.last_signal_position = None  # 记录最后一个信号点的位置
        self.last_signal_type = None      # 记录最后一个信号的类型
        self.white_circle_active = False  # 记录是否处于白色圆圈激活状态
        
    def _load_templates(self) -> Dict:
        """加载模板图像"""
        templates = {}
        for pattern, path in config.CHART_CONFIG['pattern_templates'].items():
            try:
                template = cv2.imread(path)
                if template is not None:
                    templates[pattern] = template
            except Exception as e:
                logging.error(f"加载模板 {pattern} 失败: {str(e)}")
        return templates
        
    def _find_mt4_chart_window(self, symbol: str, timeframe: str) -> Optional[int]:
        """查找MT4图表窗口"""
        try:
            # 构建窗口标题
            window_title = f"{symbol} - {timeframe} - MetaTrader 4"
            
            # 查找窗口
            def callback(hwnd, extra):
                if win32gui.IsWindowVisible(hwnd):
                    title = win32gui.GetWindowText(hwnd)
                    if window_title in title:
                        extra.append(hwnd)
                return True
                
            windows = []
            win32gui.EnumWindows(callback, windows)
            
            if windows:
                return windows[0]
            return None
            
        except Exception as e:
            logging.error(f"查找MT4图表窗口失败: {str(e)}")
            return None
            
    def _get_chart_region(self, hwnd: int) -> Tuple[int, int, int, int]:
        """获取图表区域"""
        try:
            # 获取窗口位置和大小
            left, top, right, bottom = win32gui.GetWindowRect(hwnd)
            
            # 获取客户区位置
            client_left, client_top, client_right, client_bottom = win32gui.GetClientRect(hwnd)
            client_left, client_top = win32gui.ClientToScreen(hwnd, (client_left, client_top))
            client_right, client_bottom = win32gui.ClientToScreen(hwnd, (client_right, client_bottom))
            
            # 计算图表区域（排除工具栏和状态栏）
            chart_top = client_top + 50  # 工具栏高度
            chart_bottom = client_bottom - 20  # 状态栏高度
            
            return (client_left, chart_top, client_right - client_left, chart_bottom - chart_top)
            
        except Exception as e:
            logging.error(f"获取图表区域失败: {str(e)}")
            return config.CHART_CONFIG['chart_region']
        
    def _capture_chart(self, symbol: str, timeframe: str) -> np.ndarray:
        """捕获MT4图表窗口"""
        try:
            # 查找图表窗口
            hwnd = self._find_mt4_chart_window(symbol, timeframe)
            if hwnd is None:
                logging.error(f"未找到{symbol} {timeframe}的图表窗口")
                return np.zeros((600, 800, 3), dtype=np.uint8)
                
            # 激活窗口
            print(f"正在激活MT4窗口...")
            win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)  # 如果窗口最小化，恢复它
            win32gui.SetForegroundWindow(hwnd)  # 将窗口带到前台
            
            # 等待窗口激活
            time.sleep(0.5)  # 等待窗口完全激活
            
            # 获取图表区域
            region = self._get_chart_region(hwnd)
            
            # 截图
            screenshot = pyautogui.screenshot(region=region)
            image = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR)
            
            # 保存截图用于调试
            cv2.imwrite(f"debug_{symbol}_{timeframe}.png", image)
            
            return image
            
        except Exception as e:
            logging.error(f"图表截图失败: {str(e)}")
            return np.zeros((600, 800, 3), dtype=np.uint8)
            
    def analyze(self, image: np.ndarray) -> Dict:
        """分析图表数据"""
        try:
            # 分析图表形态
            pattern_analysis = self._analyze_patterns(image)
            
            # 计算技术指标
            indicators = self._calculate_indicators(image)
            
            # 生成交易信号
            signal = self._generate_trade_signal(pattern_analysis, indicators)
            
            return {
                'pattern_analysis': pattern_analysis,
                'indicators': indicators,
                'signal': signal
            }
        except Exception as e:
            logging.error(f"图表分析失败: {str(e)}")
            return {
                'pattern_analysis': {},
                'indicators': {},
                'signal': {'should_trade': False}
            }
        
    def _analyze_patterns(self, image: np.ndarray) -> Dict:
        """分析图表形态"""
        results = {
            'patterns': [],
            'confidence': 0
        }
        
        try:
            # 暂时返回空结果，后续实现形态识别
            pass
            
        except Exception as e:
            logging.error(f"形态分析失败: {str(e)}")
        
        return results
        
    def _calculate_indicators(self, image: np.ndarray) -> Dict:
        """计算技术指标"""
        indicators = {
            'trend': 0,  # 趋势方向：-1下跌，0震荡，1上涨
            'strength': 0,  # 趋势强度：0-100
            'volatility': 0,  # 波动率：0-100
            'support_resistance': []  # 支撑阻力位
        }
        
        try:
            # 暂时返回默认值，后续实现指标计算
            pass
            
        except Exception as e:
            logging.error(f"指标计算失败: {str(e)}")
            
        return indicators
        
    def _generate_trade_signal(self, pattern_analysis: Dict, indicators: Dict) -> Dict:
        """生成交易信号"""
        signal = {
            'should_trade': False,
            'direction': 0,  # 0空单，1多单，2双向
            'confidence': 0,
            'target_price': 0,
            'stop_price': 0
        }
        
        try:
            # 暂时返回默认信号，后续实现信号生成
            pass
            
        except Exception as e:
            logging.error(f"信号生成失败: {str(e)}")
            
        return signal

    def analyze_pattern(self, symbol: str, timeframe: str) -> Tuple[SignalType, dict]:
        """
        分析图表形态并返回交易信号
        :param symbol: 交易对
        :param timeframe: 时间周期
        :return: (信号类型, 附加信息)
        """
        try:
            # 获取图表图像
            chart_image = self.chart_capturer.capture_chart(symbol, timeframe, save_debug=True)
            if chart_image is None:
                return SignalType.NO_SIGNAL, {"error": "无法获取图表图像"}
                
            # 预处理图像（用于其他分析）
            processed_image = self.chart_capturer.preprocess_image(chart_image, symbol, timeframe, save_debug=True)
            
            # 检测标记和趋势（使用预处理图像）
            markers = self._detect_markers(processed_image)
            trend_info = self._analyze_trend_markers(processed_image)
            
            print("\n=== 开始副图分析 ===")
            # 副图分析使用原始图像
            sub_chart_trend = self._analyze_sub_chart_histogram_v2(chart_image)
            print(f"副图趋势分析结果: {sub_chart_trend}")
            
            # 获取最新的信号圆圈（最右边的）
            latest_circle = self._get_latest_circle(markers.get("signal_circles"))
            
            if latest_circle:
                circle_type = latest_circle["color"]
                circle_position = latest_circle["position"]
                
                print(f"\n=== 信号分析 ===")
                print(f"检测到{circle_type}色信号")
                print(f"副图趋势: {sub_chart_trend}")
                
                # 如果是蓝色圆圈（做多信号）
                if circle_type == "blue":
                    # 检查副图柱状图是否朝上
                    if sub_chart_trend == "up":
                        print("满足做多条件：蓝色信号 + 副图向上")
                        stop_loss = circle_position[1] + latest_circle["radius"]  # 圆圈下沿位置
                        return SignalType.BUY, {
                            "reason": "检测到蓝色买入信号且副图柱线朝上",
                            "position": circle_position,
                            "stop_loss": stop_loss,
                            "sub_chart_trend": "up"
                        }
                    else:
                        print("不满足做多条件：副图未向上")
                        return SignalType.NO_SIGNAL, {
                            "reason": "检测到蓝色标记但副图柱线未朝上",
                            "sub_chart_trend": sub_chart_trend
                        }
                
                # 如果是红色圆圈（做空信号）
                elif circle_type == "red":
                    # 检查副图柱状图是否朝下
                    if sub_chart_trend == "down":
                        print("满足做空条件：红色信号 + 副图向下")
                        stop_loss = circle_position[1] - latest_circle["radius"]  # 圆圈上沿位置
                        return SignalType.SELL, {
                            "reason": "检测到红色卖出信号且副图柱线朝下",
                            "position": circle_position,
                            "stop_loss": stop_loss,
                            "sub_chart_trend": "down"
                        }
                    else:
                        print("不满足做空条件：副图未向下")
                        return SignalType.NO_SIGNAL, {
                            "reason": "检测到红色标记但副图柱线未朝下",
                            "sub_chart_trend": sub_chart_trend
                        }
                        
                # 如果是白色圆圈，停止开启新订单
                elif circle_type == "white":
                    print("检测到白色平仓信号")
                    return SignalType.NO_SIGNAL, {
                        "reason": "检测到白色标记，停止开启新订单",
                        "position": circle_position
                    }
            
            # 检查副图柱状图趋势变化
            if sub_chart_trend == "down" and self.last_signal_type == SignalType.BUY:
                print("副图转向下方，暂停开启新多单")
                return SignalType.NO_SIGNAL, {
                    "reason": "副图柱线朝下，暂停开启新多单",
                    "sub_chart_trend": "down"
                }
            elif sub_chart_trend == "up" and self.last_signal_type == SignalType.SELL:
                print("副图转向上方，暂停开启新空单")
                return SignalType.NO_SIGNAL, {
                    "reason": "副图柱线朝上，暂停开启新空单",
                    "sub_chart_trend": "up"
                }
            
            return SignalType.NO_SIGNAL, {
                "reason": "未检测到有效信号",
                "trend_info": trend_info
            }
            
        except Exception as e:
            logging.error(f"图表分析失败: {str(e)}")
            return SignalType.NO_SIGNAL, {"error": str(e)}
            
    def _get_latest_circle(self, circles: List[dict]) -> Optional[dict]:
        """
        获取最新（最右边）的信号圆圈
        """
        if not circles:
            return None
            
        # 按x坐标排序，获取最右边的圆圈
        latest_circle = max(circles, key=lambda c: c["position"][0])
        
        # 直接返回圆圈信息
        return latest_circle
        
    def _analyze_sub_chart_histogram(self, image: np.ndarray) -> str:
        """
        分析副图柱状图趋势，通过精确定位0.00文字来确定0线位置
        """
        try:
            # 获取图像下方1/4区域（副图区域）
            height = image.shape[0]
            sub_chart_region = image[int(3*height/4):, :]
            sub_chart_height = sub_chart_region.shape[0]
            
            # 保存副图区域
            debug_dir = "I:/code/xardfx/debug_images"
            if not os.path.exists(debug_dir):
                os.makedirs(debug_dir)
            cv2.imwrite(os.path.join(debug_dir, "1_sub_chart_region.png"), sub_chart_region)
            
            # 状态栏高度（估计约20像素）
            status_bar_height = 20
            
            # 实际的副图高度（不包括状态栏）
            actual_chart_height = sub_chart_height - status_bar_height
            
            # 获取最右侧区域用于识别0.00文字
            right_text_region = sub_chart_region[:, -60:]  # 取最右侧60像素宽度的区域
            cv2.imwrite(os.path.join(debug_dir, "2_right_text_region.png"), right_text_region)
            
            # 转换为灰度图用于文字识别
            gray = cv2.cvtColor(right_text_region, cv2.COLOR_BGR2GRAY)
            cv2.imwrite(os.path.join(debug_dir, "3_gray_text_region.png"), gray)
            
            # 创建掩码，只保留浅灰色文字（0.00的颜色范围）
            light_gray_mask = cv2.inRange(right_text_region, np.array([160, 160, 160]), np.array([190, 190, 190]))
            cv2.imwrite(os.path.join(debug_dir, "4_light_gray_mask.png"), light_gray_mask)
            
            # 查找轮廓
            contours, _ = cv2.findContours(light_gray_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            
            # 在调试图像上标记所有找到的轮廓
            debug_contours = cv2.cvtColor(light_gray_mask, cv2.COLOR_GRAY2BGR)
            
            # 找到0.00文字的位置
            zero_line_y = None
            zero_contours = []
            
            # 首先找到所有可能的数字轮廓
            for contour in contours:
                x, y, w, h = cv2.boundingRect(contour)
                area = cv2.contourArea(contour)
                # 过滤掉太小的轮廓
                if area > 20:  # 调整面积阈值以过滤噪声
                    zero_contours.append((x, y, w, h))
                    # 在调试图像上画矩形
                    cv2.rectangle(debug_contours, (x, y), (x+w, y+h), (0, 255, 0), 1)
            
            cv2.imwrite(os.path.join(debug_dir, "5_contours_marked.png"), debug_contours)
            
            # 找到0.00所在的位置
            if zero_contours:
                # 按y坐标排序找到的轮廓
                zero_contours.sort(key=lambda x: x[1])
                
                # 找到中间位置的轮廓（通常是0.00）
                middle_index = len(zero_contours) // 2
                if middle_index < len(zero_contours):
                    x, y, w, h = zero_contours[middle_index]
                    # 使用轮廓的中心位置作为0线
                    zero_line_y = y + h // 2
                    print(f"找到0.00文字，中心线位置: y={zero_line_y}")
                    
                    # 在调试图像上标记0线位置
                    debug_zero_line = right_text_region.copy()
                    cv2.line(debug_zero_line, (0, zero_line_y), (right_text_region.shape[1], zero_line_y), (0, 255, 255), 1)
                    cv2.imwrite(os.path.join(debug_dir, "6_zero_line_marked.png"), debug_zero_line)
            
            if zero_line_y is None:
                print("警告：未能找到0.00文字位置，使用默认位置")
                zero_line_y = actual_chart_height // 2
            
            # 检查最新柱线的位置（向左偏移一些）
            right_region_width = 10  # 检测区域宽度
            offset_from_right = 367  # 从右边缘向左偏移的像素数（包括文字区域的60像素和额外偏移）
            right_region = sub_chart_region[:, -offset_from_right:-offset_from_right+right_region_width]  # 取偏移后的区域
            cv2.imwrite(os.path.join(debug_dir, "7_detection_region.png"), right_region)
            
            # 创建一个彩色图像用于显示检测结果
            debug_detection = sub_chart_region.copy()
            # 在图像上标记检测区域
            cv2.rectangle(debug_detection, 
                         (sub_chart_region.shape[1]-offset_from_right, 0),
                         (sub_chart_region.shape[1]-offset_from_right+right_region_width, sub_chart_region.shape[0]),
                         (0, 255, 0), 2)
            cv2.imwrite(os.path.join(debug_dir, "8_detection_area_marked.png"), debug_detection)
            
            # 分别统计0线上下的柱线像素和颜色
            def is_bar_pixel(pixel):
                # 检查像素是否为柱状图的一部分
                b, g, r = pixel
                
                # 检查是否为背景色
                is_background = (b < 20 and g < 20 and r < 20)  # 降低背景色阈值
                
                # 检查是否为红色柱线（放宽红色判定条件）
                is_red = (r > 100 and r > max(b, g) * 1.2)  # 降低红色阈值，保持比例判断
                
                # 检查是否为蓝色柱线（放宽蓝色判定条件）
                is_blue = (b > 100 and b > max(r, g) * 1.2)  # 降低蓝色阈值，保持比例判断
                
                return (is_red or is_blue) and not is_background, is_red, is_blue
            
            # 创建一个用于显示像素分类的调试图像
            debug_pixel_classification = right_region.copy()
            pixels_above = 0
            pixels_below = 0
            red_pixels = 0
            blue_pixels = 0
            
            # 遍历检测区域的每个像素（不包括状态栏区域）
            for y in range(min(right_region.shape[0], actual_chart_height)):
                pixel = right_region[y, right_region_width//2]  # 取中间一列的像素
                is_bar, is_red, is_blue = is_bar_pixel(pixel)
                if is_bar:
                    # 在调试图像中标记像素
                    if is_red:
                        debug_pixel_classification[y, right_region_width//2] = [0, 0, 255]  # 红色
                        red_pixels += 1
                    if is_blue:
                        debug_pixel_classification[y, right_region_width//2] = [255, 0, 0]  # 蓝色
                        blue_pixels += 1
                    # 使用相对于实际副图区域的y坐标来判断位置
                    if y < zero_line_y:
                        pixels_above += 1
                    else:
                        pixels_below += 1
            
            cv2.imwrite(os.path.join(debug_dir, "9_pixel_classification.png"), debug_pixel_classification)
            
            # 创建一个显示统计结果的图像
            debug_stats = np.zeros((200, 400, 3), dtype=np.uint8)
            cv2.putText(debug_stats, f"Pixels above: {pixels_above}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
            cv2.putText(debug_stats, f"Pixels below: {pixels_below}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
            cv2.putText(debug_stats, f"Red pixels: {red_pixels}", (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
            cv2.putText(debug_stats, f"Blue pixels: {blue_pixels}", (10, 120), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2)
            cv2.imwrite(os.path.join(debug_dir, "10_pixel_stats.png"), debug_stats)
            
            # 设置一个最小像素阈值，确保确实检测到了柱线
            min_pixels = 5
            # 设置一个差异阈值，确保上下像素数有明显差异
            diff_threshold = 10
            
            print("\n=== 副图柱线分析 ===")
            
            # 获取颜色信息
            color_info = ""
            if blue_pixels > red_pixels and blue_pixels > min_pixels:
                color_info = "蓝色"
            elif red_pixels > blue_pixels and red_pixels > min_pixels:
                color_info = "红色"
            
            # 获取位置信息
            position_info = ""
            if pixels_above > pixels_below + diff_threshold and pixels_above > min_pixels:
                position_info = "0线以上"
            elif pixels_below > pixels_above + diff_threshold and pixels_below > min_pixels:
                position_info = "0线以下"
            
            # 输出综合信息并返回趋势（优先判断位置信息）
            if position_info:
                if color_info:
                    print(f"柱线分析结果: {color_info}柱线，位于{position_info}")
                else:
                    print(f"柱线分析结果: 位于{position_info}")
                    
                if position_info == "0线以上":
                    return "up"
                else:
                    return "down"
            elif color_info:
                print(f"柱线分析结果: {color_info}柱线")
                if color_info == "蓝色":
                    return "up"
                else:
                    return "down"
            else:
                print("柱线分析结果: 趋势不明确")
                return "neutral"
            
        except Exception as e:
            logging.error(f"副图分析失败: {str(e)}")
            return "neutral"
        
    def _analyze_sub_chart_histogram_v2(self, image: np.ndarray) -> str:
        """
        分析副图柱状图趋势的第二个版本
        - 使用固定的0线位置(y=85)
        - 分析次右和次次右的柱线来判断趋势
        - 只使用位置关系判断趋势，不依赖颜色
        """
        try:
            print("\n=== 副图分析V2 ===")
            print("1. 开始分析副图区域...")
            
            # 获取图像下方1/4区域（副图区域）
            height = image.shape[0]
            sub_chart_region = image[int(3*height/4):, :]
            sub_chart_height = sub_chart_region.shape[0]
            print(f"副图区域尺寸: {sub_chart_region.shape}")
            
            # 保存副图区域
            debug_dir = "I:/code/xardfx/debug_images/v2"
            if not os.path.exists(debug_dir):
                os.makedirs(debug_dir)
            cv2.imwrite(os.path.join(debug_dir, "1_sub_chart_region.png"), sub_chart_region)
            
            # 固定0线位置
            zero_line_y = 85
            print(f"固定0线位置: y={zero_line_y}")
            
            # 检查柱线的位置（从右向左第二根和第三根）
            bar_width = 7  # 检测区域宽度
            right_offset = 367  # 从右边缘向左偏移的像素数（包括文字区域的60像素和额外偏移）
            print(f"柱线检测参数: 宽度={bar_width}, 右偏移={right_offset}")
            
            # 获取次右柱线区域（固定位置）
            second_right_region = sub_chart_region[:, -right_offset:-right_offset+bar_width]
            cv2.imwrite(os.path.join(debug_dir, "2_second_right_bar.png"), second_right_region)
            
            # 获取次次右柱线区域（在次右柱线基础上再往左两个柱子宽度）
            third_right_offset = right_offset + bar_width 
            third_right_region = sub_chart_region[:, -third_right_offset:-third_right_offset+bar_width]
            cv2.imwrite(os.path.join(debug_dir, "3_third_right_bar.png"), third_right_region)
            
            # 创建一个调试图像显示检测区域
            debug_detection = sub_chart_region.copy()
            # 标记次右柱线区域
            cv2.rectangle(debug_detection, 
                         (sub_chart_region.shape[1]-right_offset, 0),
                         (sub_chart_region.shape[1]-right_offset+bar_width, sub_chart_region.shape[0]),
                         (0, 255, 0), 2)
            # 标记次次右柱线区域
            cv2.rectangle(debug_detection, 
                         (sub_chart_region.shape[1]-third_right_offset, 0),
                         (sub_chart_region.shape[1]-third_right_offset+bar_width, sub_chart_region.shape[0]),
                         (255, 0, 0), 2)
            # 标记0线
            cv2.line(debug_detection, (0, zero_line_y), (debug_detection.shape[1], zero_line_y), (0, 255, 255), 1)
            cv2.imwrite(os.path.join(debug_dir, "4_detection_areas.png"), debug_detection)
            
            def analyze_bar_position(region: np.ndarray) -> Tuple[int, int, bool]:
                """分析柱线位置，返回(0线上像素数, 0线下像素数, 是否有柱线)"""
                pixels_above = 0
                pixels_below = 0
                has_bar = False
                
                # 找到柱线的最高点
                min_y = region.shape[0]  # 初始化为最大可能值
                
                # 首先找到柱线的最高点
                for y in range(region.shape[0]):
                    pixel = region[y, bar_width//2]  # 取中间一列的像素
                    b, g, r = pixel
                    
                    # 检查是否为红色柱线
                    is_red = (r > 100 and r > max(b, g) * 1.2)
                    # 检查是否为蓝色柱线
                    is_blue = (b > 100 and b > max(r, g) * 1.2)
                    
                    # 只有红色或蓝色的像素才被认为是柱线的一部分
                    if is_red or is_blue:
                        has_bar = True
                        if y < min_y:
                            min_y = y
                
                if has_bar:
                    print(f"柱线最高点: y={min_y}")
                    # 根据最高点判断柱线位置
                    if min_y < zero_line_y:
                        pixels_above = 1  # 只需要标记有柱线在0线上
                    else:
                        pixels_below = 1  # 只需要标记有柱线在0线下
                
                return pixels_above, pixels_below, has_bar
            
            print("\n2. 开始分析柱线位置...")
            
            # 分析次右柱线
            second_above, second_below, second_has_bar = analyze_bar_position(second_right_region)
            print(f"次右柱线分析:")
            print(f"- 是否有柱线: {second_has_bar}")
            print(f"- 0线上像素数: {second_above}")
            print(f"- 0线下像素数: {second_below}")
            
            # 分析次次右柱线
            third_above, third_below, third_has_bar = analyze_bar_position(third_right_region)
            print(f"次次右柱线分析:")
            print(f"- 是否有柱线: {third_has_bar}")
            print(f"- 0线上像素数: {third_above}")
            print(f"- 0线下像素数: {third_below}")
            
            # 创建统计信息图像
            debug_stats = np.zeros((300, 500, 3), dtype=np.uint8)
            cv2.putText(debug_stats, "Second Right Bar:", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
            cv2.putText(debug_stats, f"Above: {second_above}, Below: {second_below}", (20, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
            cv2.putText(debug_stats, f"Has Bar: {second_has_bar}", (20, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
            
            cv2.putText(debug_stats, "Third Right Bar:", (10, 150), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
            cv2.putText(debug_stats, f"Above: {third_above}, Below: {third_below}", (20, 180), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
            cv2.putText(debug_stats, f"Has Bar: {third_has_bar}", (20, 210), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
            cv2.imwrite(os.path.join(debug_dir, "5_analysis_stats.png"), debug_stats)
            
            print("\n3. 开始判断趋势...")
            
            # 判断趋势
            if second_has_bar:
                # 判断最右柱线位置
                second_is_above = second_above > second_below
                print(f"最右柱线位置: {'0线上' if second_is_above else '0线下'}")
                
                if second_is_above:
                    # 最右柱线在中线上
                    if not third_has_bar or third_above < third_below:
                        print("检测到上涨趋势：最右柱线在中线上，次右柱线在中线下或无")
                        return "up"
                else:
                    # 最右柱线在中线下
                    if not third_has_bar or third_above > third_below:
                        print("检测到下跌趋势：最右柱线在中线下，次右柱线在中线上或无")
                        return "down"
            
            print("未检测到有效趋势信号")
            return "neutral"
            
        except Exception as e:
            logging.error(f"副图分析V2失败: {str(e)}")
            return "neutral"
        
    def _detect_candlestick_pattern(self, image: np.ndarray) -> Optional[dict]:
        """
        检测K线形态
        :param image: 预处理后的图像
        :return: 形态信息字典或None
        """
        # TODO: 实现K线形态检测逻辑
        pass
        
    def _detect_trend_lines(self, image: np.ndarray) -> Optional[dict]:
        """
        检测趋势线
        :param image: 预处理后的图像
        :return: 趋势线信息字典或None
        """
        # TODO: 实现趋势线检测逻辑
        pass
        
    def _detect_support_resistance(self, image: np.ndarray) -> Optional[dict]:
        """
        检测支撑和阻力位
        :param image: 预处理后的图像
        :return: 支撑阻力位信息字典或None
        """
        # TODO: 实现支撑阻力位检测逻辑
        pass
        
    def _detect_markers(self, image: np.ndarray) -> dict:
        """
        检测图表上的标记
        """
        try:
            markers = {
                "signal_circles": [],
                "trend_lines": [],
                "support_resistance": [],
                "colored_areas": []
            }
            
            # 获取图像高度
            height = image.shape[0]
            
            # 只取主图区域(排除副图和状态栏)
            main_chart_height = int(3 * height / 4)  # 主图高度
            main_chart_region = image[:main_chart_height, :]
            
            # 创建一个用于标注的图像副本
            debug_image = main_chart_region.copy()
            
            # 用于去重的辅助函数
            def is_duplicate_circle(circles, x, y, min_distance=15):
                for circle in circles:
                    cx, cy = circle["position"]
                    if np.sqrt((x - cx) ** 2 + (y - cy) ** 2) < min_distance:
                        print(f"跳过重复圆圈: ({x}, {y})")
                        return True
                return False

            # 确保图像是BGR格式
            if len(main_chart_region.shape) == 2:
                main_chart_region = cv2.cvtColor(main_chart_region, cv2.COLOR_GRAY2BGR)
            
            # 创建一个图像副本用于圆圈检测
            detection_image = main_chart_region.copy()
            
            # 轻微增强对比度（仅用于圆圈检测）
            lab = cv2.cvtColor(detection_image, cv2.COLOR_BGR2LAB)
            l, a, b = cv2.split(lab)
            clahe = cv2.createCLAHE(clipLimit=1.5, tileGridSize=(8,8))
            cl = clahe.apply(l)
            enhanced = cv2.merge((cl,a,b))
            enhanced = cv2.cvtColor(enhanced, cv2.COLOR_LAB2BGR)
            
            # 转换为灰度图
            gray = cv2.cvtColor(enhanced, cv2.COLOR_BGR2GRAY)
            
            print("\n=== 开始检测信号圆圈 ===")
            detected_circles = []
            
            # 检测所有圆圈（红、蓝、白）
            circles = cv2.HoughCircles(
                gray,
                cv2.HOUGH_GRADIENT,
                dp=1,
                minDist=20,
                param1=50,
                param2=25,
                minRadius=3,
                maxRadius=15
            )
            
            # 创建调试目录
            debug_dir = "I:/code/xardfx/debug_images/circles"
            if not os.path.exists(debug_dir):
                os.makedirs(debug_dir)
            
            if circles is not None:
                circles = np.uint16(np.around(circles))
                
                # 按x坐标从大到小排序（从右到左）
                sorted_circles = sorted(circles[0], key=lambda c: c[0], reverse=True)
                
                # 只处理最右侧1/2区域的圆圈
                right_boundary = main_chart_region.shape[1] / 2
                right_circles = [c for c in sorted_circles if c[0] > right_boundary]
                
                if right_circles:
                    for circle in right_circles:
                        x, y, r = circle
                        
                        # 检查是否是右上角图标
                        if x > main_chart_region.shape[1] * 0.85 and y < main_chart_region.shape[0] * 0.2:
                            continue
                        
                        if not is_duplicate_circle(detected_circles, x, y):
                            # 检查红蓝环信号
                            ring_mask = np.zeros(main_chart_region.shape[:2], dtype=np.uint8)
                            cv2.circle(ring_mask, (int(x), int(y)), int(r), 255, 4)  # 4像素宽度的环
                            
                            # 获取圆环区域的BGR值
                            ring_pixels = main_chart_region[ring_mask > 0]
                            if len(ring_pixels) > 0:
                                mean_bgr = np.mean(ring_pixels, axis=0)
                                b, g, r_val = mean_bgr  # 重命名为r_val避免覆盖原始半径r
                                
                                # 检查是否为蓝色环
                                if b > 100 and b > max(r_val, g) * 1.2:
                                    # 检查中心是否为亮色
                                    center_mask = np.zeros(main_chart_region.shape[:2], dtype=np.uint8)
                                    cv2.circle(center_mask, (int(x), int(y)), int(r-4), 255, -1)
                                    center_pixels = main_chart_region[center_mask > 0]
                                    if len(center_pixels) > 0:
                                        center_bgr = np.mean(center_pixels, axis=0)
                                        cb, cg, cr = center_bgr
                                        if cr > 150 and cg > 150 and cb > 150:  # 中心为亮色
                                            print(f"检测到蓝色买入信号: ({x}, {y})")
                                            circle_info = {
                                                "position": (int(x), int(y)),
                                                "radius": int(r),
                                                "color": "blue",
                                                "type": "blue"
                                            }
                                            detected_circles.append(circle_info)
                                            markers["signal_circles"].append(circle_info)
                                            # 在调试图像上标注蓝色圆圈
                                            cv2.circle(debug_image, (int(x), int(y)), int(r), (255, 0, 0), 2)
                                            cv2.putText(debug_image, "Blue", (int(x)+15, int(y)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1)
                                            continue
                                
                                # 检查是否为红色环
                                elif r_val > 100 and r_val > max(b, g) * 1.2:
                                    # 检查中心是否为亮色
                                    center_mask = np.zeros(main_chart_region.shape[:2], dtype=np.uint8)
                                    cv2.circle(center_mask, (int(x), int(y)), int(r-4), 255, -1)
                                    center_pixels = main_chart_region[center_mask > 0]
                                    if len(center_pixels) > 0:
                                        center_bgr = np.mean(center_pixels, axis=0)
                                        cb, cg, cr = center_bgr
                                        if cr > 150 and cg > 150 and cb > 150:  # 中心为亮色
                                            print(f"检测到红色卖出信号: ({x}, {y})")
                                            circle_info = {
                                                "position": (int(x), int(y)),
                                                "radius": int(r),
                                                "color": "red",
                                                "type": "red"
                                            }
                                            detected_circles.append(circle_info)
                                            markers["signal_circles"].append(circle_info)
                                            # 在调试图像上标注红色圆圈
                                            cv2.circle(debug_image, (int(x), int(y)), int(r), (0, 0, 255), 2)
                                            cv2.putText(debug_image, "Red", (int(x)+15, int(y)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
                                            continue

                            # 最后才检查是否为白色实心圆（平仓信号）
                            center_mask = np.zeros(main_chart_region.shape[:2], dtype=np.uint8)
                            cv2.circle(center_mask, (int(x), int(y)), int(r), 255, -1)
                            center_pixels = main_chart_region[center_mask > 0]
                            if len(center_pixels) > 0:
                                center_bgr = np.mean(center_pixels, axis=0)
                                b, g, r_val = center_bgr
                                # 更严格的白色判定条件
                                if (r_val > 200 and g > 200 and b > 200) and (max(r_val, g, b) - min(r_val, g, b) < 30):
                                    print(f"检测到白色平仓信号: ({x}, {y})")
                                    circle_info = {
                                        "position": (int(x), int(y)),
                                        "radius": int(r),
                                        "color": "white",
                                        "type": "white"
                                    }
                                    detected_circles.append(circle_info)
                                    markers["signal_circles"].append(circle_info)
                                    # 在调试图像上标注白色圆圈（使用黄色来标注）
                                    cv2.circle(debug_image, (int(x), int(y)), int(r), (0, 255, 255), 2)
                                    cv2.putText(debug_image, "White", (int(x)+15, int(y)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 1)
                                    continue
            
            # 保存标注后的调试图像
            cv2.imwrite(os.path.join(debug_dir, "detected_circles.png"), debug_image)
            
            print(f"\n=== 检测完成，共发现 {len(markers['signal_circles'])} 个信号 ===")
            
            return markers
            
        except Exception as e:
            logging.error(f"标记检测失败: {str(e)}")
            return markers
            
    def _detect_ma_line(self, image: np.ndarray) -> Optional[dict]:
        """
        检测MA线
        :param image: 预处理后的图像
        :return: MA线信息字典或None
        """
        try:
            # 转换为HSV颜色空间
            hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
            
            # 检测青色MA线
            cyan_mask = cv2.inRange(hsv, np.array([85, 100, 100]), np.array([95, 255, 255]))
            
            # 使用霍夫变换检测直线
            lines = cv2.HoughLinesP(cyan_mask, 1, np.pi/180, 50, minLineLength=100, maxLineGap=10)
            
            if lines is not None:
                # 计算所有直线的平均y坐标
                total_y = 0
                count = 0
                for line in lines:
                    x1, y1, x2, y2 = line[0]
                    total_y += (y1 + y2) / 2
                    count += 1
                
                if count > 0:
                    avg_y = int(total_y / count)
                    print(f"检测到MA线，平均y坐标: {avg_y}")
                    return {"y": avg_y}
            
            return None
            
        except Exception as e:
            logging.error(f"MA线检测失败: {str(e)}")
            return None
        
    def _get_solid_circle_color(self, image: np.ndarray, x: int, y: int, r: int) -> str:
        """
        获取实心圆点的颜色
        """
        try:
            # 创建实心圆掩码
            mask = np.zeros(image.shape[:2], dtype=np.uint8)
            cv2.circle(mask, (int(x), int(y)), int(r), 255, -1)  # -1表示填充
            
            # 获取圆形区域的平均颜色
            mean_color = cv2.mean(image, mask=mask)[:3]  # BGR格式
            b, g, r = mean_color
            print(f"检测到的实心圆颜色值: BGR=({b}, {g}, {r})")
            
            # 判断是否为纯白色（所有通道都接近255）
            if r > 200 and g > 200 and b > 200:
                return "white"
            return "unknown"
                
        except Exception as e:
            logging.error(f"颜色检测失败: {str(e)}")
            return "unknown"
            
    def _get_ring_color(self, image: np.ndarray, x: int, y: int, r: int) -> str:
        """
        获取圆环的颜色
        """
        try:
            # 创建圆环掩码
            mask = np.zeros(image.shape[:2], dtype=np.uint8)
            # 画一个较粗的圆环
            cv2.circle(mask, (int(x), int(y)), int(r), 255, 2)
            
            # 获取圆环区域的平均颜色
            mean_color = cv2.mean(image, mask=mask)[:3]  # BGR格式
            b, g, r = mean_color
            print(f"\n圆环颜色分析:")
            print(f"BGR值: B={b:.1f}, G={g:.1f}, R={r:.1f}")
            
            # 计算颜色比例
            total = b + g + r
            if total > 0:
                b_ratio = b / total
                r_ratio = r / total
                g_ratio = g / total
                print(f"颜色比例: R={r_ratio:.2f}, G={g_ratio:.2f}, B={b_ratio:.2f}")
                
                # 判断圆环颜色
                print("\n颜色判断条件:")
                # 红色判断
                print(f"红色条件检查:")
                print(f"1. R > 50: {r > 50} (R={r:.1f})")
                print(f"2. R比例 > 0.4: {r_ratio > 0.4} (R比例={r_ratio:.2f})")
                print(f"3. G < R*0.8: {g < r * 0.8} (G={g:.1f}, R*0.8={r*0.8:.1f})")
                if r > 50 and r_ratio > 0.4 and g < r * 0.8:
                    print("==> 满足红色条件")
                    return "red"
                    
                # 蓝色判断
                print(f"\n蓝色条件检查:")
                print(f"1. B > 50: {b > 50} (B={b:.1f})")
                print(f"2. B比例 > 0.4: {b_ratio > 0.4} (B比例={b_ratio:.2f})")
                print(f"3. G < B*0.8: {g < b * 0.8} (G={g:.1f}, B*0.8={b*0.8:.1f})")
                if b > 50 and b_ratio > 0.4 and g < b * 0.8:
                    print("==> 满足蓝色条件")
                    return "blue"
            
            print("==> 不满足任何颜色条件，判定为unknown")
            return "unknown"
                
        except Exception as e:
            logging.error(f"颜色检测失败: {str(e)}")
            return "unknown"
            
    def _analyze_trend_markers(self, image: np.ndarray) -> dict:
        """
        分析趋势标记
        """
        try:
            trend_info = {
                "trend_direction": None,  # up, down, or None
                "support_level": None,
                "resistance_level": None,
                "ma_trend": None,
                "trend_lines": [],
                "support_resistance": []
            }
            
            # 转换为HSV颜色空间
            hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
            
            # 检测黄色支撑/阻力线
            yellow_mask = cv2.inRange(hsv, np.array([20, 100, 100]), np.array([30, 255, 255]))
            yellow_lines = cv2.HoughLinesP(yellow_mask, 1, np.pi/180, 50, minLineLength=100, maxLineGap=10)
            if yellow_lines is not None:
                for line in yellow_lines:
                    x1, y1, x2, y2 = line[0]
                    trend_info["support_resistance"].append({
                        "points": (int(x1), int(y1), int(x2), int(y2)),
                        "y_level": int((y1 + y2) / 2),
                        "color": "yellow"
                    })
                    print(f"检测到支撑/阻力线，位置: ({x1}, {y1}) - ({x2}, {y2})")
            
            # 检测青色移动平均线
            cyan_mask = cv2.inRange(hsv, np.array([85, 100, 100]), np.array([95, 255, 255]))
            cyan_lines = cv2.HoughLinesP(cyan_mask, 1, np.pi/180, 50, minLineLength=100, maxLineGap=10)
            if cyan_lines is not None:
                for line in cyan_lines:
                    x1, y1, x2, y2 = line[0]
                    trend_info["trend_lines"].append({
                        "points": (int(x1), int(y1), int(x2), int(y2)),
                        "color": "cyan"
                    })
                    # 判断MA趋势
                    if y2 < y1:
                        trend_info["ma_trend"] = "up"
                    elif y2 > y1:
                        trend_info["ma_trend"] = "down"
                    print(f"检测到MA线，趋势: {trend_info['ma_trend']}")
            
            # 检测白色波动通道
            white_mask = cv2.inRange(hsv, np.array([0, 0, 200]), np.array([180, 30, 255]))
            white_lines = cv2.HoughLinesP(white_mask, 1, np.pi/180, 50, minLineLength=100, maxLineGap=10)
            if white_lines is not None:
                start_y = end_y = 0
                count = 0
                for line in white_lines:
                    x1, y1, x2, y2 = line[0]
                    trend_info["trend_lines"].append({
                        "points": (int(x1), int(y1), int(x2), int(y2)),
                        "color": "white"
                    })
                    start_y += y1
                    end_y += y2
                    count += 1
                
                if count > 0:
                    start_y /= count
                    end_y /= count
                    if end_y < start_y:
                        trend_info["trend_direction"] = "up"
                    elif end_y > start_y:
                        trend_info["trend_direction"] = "down"
                    print(f"检测到波动通道，趋势: {trend_info['trend_direction']}")
            
            return trend_info
            
        except Exception as e:
            logging.error(f"趋势分析失败: {str(e)}")
            return trend_info

    def analyze_chart(self, image: np.ndarray, symbol: str = None, timeframe: str = None, save_debug: bool = False) -> Tuple[Optional[SignalType], dict]:
        """
        分析图表并返回交易信号
        :param image: 图表图像
        :param symbol: 交易对
        :param timeframe: 时间周期
        :param save_debug: 是否保存调试图片
        """
        try:
            # 获取当前实际的货币对和时间周期
            actual_symbol = None
            actual_timeframe = None
            title = win32gui.GetWindowText(self.chart_capturer.mt4_hwnd)
            print(f"\n当前MT4窗口标题: {title}")
            
            if "[" in title and "]" in title:
                chart_info = title[title.find("[")+1:title.find("]")]
                if "," in chart_info:
                    actual_symbol = chart_info.split(",")[0].strip()
                    actual_timeframe = chart_info.split(",")[1].strip()
                    print(f"\n实际图表信息: 货币对={actual_symbol}, 时间周期={actual_timeframe}")
            
            # 检查实际货币对与传入的是否一致
            if actual_symbol and symbol and actual_symbol != symbol:
                print(f"\n警告: 传入的货币对({symbol})与当前图表货币对({actual_symbol})不一致")
                print("为确保分析准确性，跳过本次分析")
                return None, {"error": "货币对不一致"}
            
            # 始终使用实际检测到的货币对，如果检测不到才使用传入的参数
            used_symbol = actual_symbol or symbol
            used_timeframe = actual_timeframe or timeframe
            
            if not used_symbol:
                print("\n错误: 无法确定要分析的货币对")
                return None, {"error": "无法确定货币对"}
                
            print(f"\n开始分析图表: {used_symbol} {used_timeframe}")
            
            # 预处理图像
            if save_debug:
                processed_image = self.chart_capturer.preprocess_image(
                    image, 
                    used_symbol,
                    used_timeframe, 
                    save_debug=True
                )
            else:
                processed_image = self.chart_capturer.preprocess_image(image, "", "", save_debug=False)
            
            # 检测标记
            print(f"\n开始检测{used_symbol}图表标记...")
            markers = self._detect_markers(processed_image)
            signal_circles = markers.get("signal_circles", [])
            
            # 分析副图柱状图趋势
            print("\n=== 开始副图分析 ===")
            # 副图分析使用原始图像
            sub_chart_trend = self._analyze_sub_chart_histogram_v2(image)
            print(f"副图趋势分析结果: {sub_chart_trend}")
            
            # 按x坐标从大到小排序（从右到左）
            signal_circles.sort(key=lambda c: c["position"][0], reverse=True)
            print(f"\n检测到的信号（从右到左排序）:")
            for i, circle in enumerate(signal_circles, 1):
                print(f"信号 {i}: 类型={circle['type']}, 位置={circle['position']}, 半径={circle['radius']}")
            
            # 获取最新的圆圈信号（最右侧的）
            latest_circle = signal_circles[0] if signal_circles else None
            
            if latest_circle:
                circle_type = latest_circle.get("type", "unknown")
                position = latest_circle.get("position", (0, 0))
                radius = latest_circle.get("radius", 0)
                print(f"\n最新信号分析:")
                print(f"货币对: {used_symbol}")
                print(f"类型: {circle_type}")
                print(f"位置: {position}")
                print(f"半径: {radius}")
                print(f"副图趋势: {sub_chart_trend}")
                
                if circle_type == "white":
                    print(f"检测到{used_symbol}白色平仓信号")
                    # 白色圆圈表示平仓信号
                    if self.last_signal_type == SignalType.BUY:
                        print("==> 生成多单平仓信号")
                        return SignalType.CLOSE_BUY, {
                            "position": position, 
                            "symbol": used_symbol,
                            "detection_time": time.time()
                        }
                    elif self.last_signal_type == SignalType.SELL:
                        print("==> 生成空单平仓信号")
                        return SignalType.CLOSE_SELL, {
                            "position": position, 
                            "symbol": used_symbol,
                            "detection_time": time.time()
                        }
                    else:
                        print("==> 无需平仓")
                        return None, {"symbol": used_symbol}
                        
                elif circle_type == "red":
                    print(f"检测到{used_symbol}红色卖出信号")
                    # 检查副图柱状图是否朝下
                    if sub_chart_trend == "down":
                        print("==> 满足做空条件：红色信号 + 副图向下")
                        # 计算止损价格（红圈上沿）
                        stop_loss_price = position[1] - radius  # 红圈上沿位置
                        self.last_signal_type = SignalType.SELL
                        return SignalType.SELL, {
                            "position": position, 
                            "symbol": used_symbol,
                            "detection_time": time.time(),
                            "sub_chart_trend": sub_chart_trend,
                            "stop_loss_price": stop_loss_price
                        }
                    else:
                        print("==> 不满足做空条件：副图未向下")
                        return SignalType.NO_SIGNAL, {
                            "reason": "检测到红色标记但副图柱线未朝下",
                            "sub_chart_trend": sub_chart_trend
                        }
                    
                elif circle_type == "blue":
                    print(f"检测到{used_symbol}蓝色买入信号")
                    # 检查副图柱状图是否朝上
                    if sub_chart_trend == "up":
                        print("==> 满足做多条件：蓝色信号 + 副图向上")
                        # 计算止损价格（蓝圈下沿）
                        stop_loss_price = position[1] + radius  # 蓝圈下沿位置
                        self.last_signal_type = SignalType.BUY
                        return SignalType.BUY, {
                            "position": position, 
                            "symbol": used_symbol,
                            "detection_time": time.time(),
                            "sub_chart_trend": sub_chart_trend,
                            "stop_loss_price": stop_loss_price
                        }
                    else:
                        print("==> 不满足做多条件：副图未向上")
                        return SignalType.NO_SIGNAL, {
                            "reason": "检测到蓝色标记但副图柱线未朝上",
                            "sub_chart_trend": sub_chart_trend
                        }
            else:
                print(f"\n未检测到{used_symbol}的有效信号标记")
                    
            return None, {"symbol": used_symbol}
            
        except Exception as e:
            logging.error(f"分析图表失败: {str(e)}")
            return None, {"error": str(e)} 